using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using NWrapper.Config;
using NWrapper.Entities;

namespace NWrapper
{
	/// <summary>
	/// Defines the basic implementation of a data repository by exposing methods to
	/// retrieve data.
	/// </summary>
	public interface IRepository
	{
		/// <summary>
		/// Initializes the repository.
		/// </summary>
		/// <param name="settings">The settings used for initialization.</param>
		void Initialize(RepositorySettings settings);

		/// <summary>
		/// Finds the first instance of a given type.
		/// </summary>
		/// <typeparam name="T">The object type.</typeparam>
		/// <returns>An object instance, or null if not found.</returns>
		T FindFirst<T>();

		/// <summary>
		/// Finds all instances of a given type.
		/// </summary>
		/// <typeparam name="T">The object type.</typeparam>
		/// <returns>An collection of object instance. If no objects are found, an empty collection is returned.</returns>
		IList<T> FindAll<T>();

		/// <summary>
		/// Saves an object to the repository.
		/// </summary>
		/// <typeparam name="T">The object type.</typeparam>
		/// <param name="target">The object to save.</param>
		void Save<T>(T target);

		/// <summary>
		/// Deletes an object from the repository.
		/// </summary>
		/// <typeparam name="T">The object type.</typeparam>
		/// <param name="target">The object to delete.</param>
		void Delete<T>(T target);

		/// <summary>
		/// Deletes all objects of a given type from the repository.
		/// </summary>
		/// <typeparam name="T">The object type.</typeparam>
		void DeleteAll<T>();

		/// <summary>
		/// Reloads an object from the repository.
		/// </summary>
		/// <typeparam name="T">The object type.</typeparam>
		/// <param name="target">The object to reload.</param>
		/// <returns>The reloaded object.</returns>
		T Resync<T>(T target);

		/// <summary>
		/// Gets the total number of records of a given type.
		/// </summary>
		/// <typeparam name="T">The object type.</typeparam>
		/// <returns>The total number of records.</returns>
		int CountAll<T>();
	}
}
